#pragma once
#pragma once

#include <assert.h>

namespace one_rag {
  namespace Core {

    template<typename ValueT>
    class Array {
    public:
      Array(int count=0, ValueT* values=0);
      ~Array();
      ValueT& operator[](int key);
      ValueT& GetAt(int key);
    protected:
      int _count;
      int _size;
      ValueT* _data;
    };

    template<typename ValueT>
    class MutableArray : public Array<ValueT>{
      using Array<ValueT>::_count;
      using Array<ValueT>::_size;
      using Array<ValueT>::_data;
      public:
      void SetAt(int index,ValueT val);
    };

    template<typename ValueT>
    Array<ValueT>::Array(int count, ValueT* values):_count(count),_size(count),_data(0)
    {
      if(count)
      {
        _data = (ValueT*)malloc(count*sizeof(ValueT));
      }
    }

    template<typename ValueT>
    Array<ValueT>::~Array(){
      free(_data);
    }

    template<typename ValueT>
    ValueT& Array<ValueT>::operator[](int key){
      assert(key < _size);
      return _data[key];
    }

    template<typename ValueT>
    void MutableArray<ValueT>::SetAt(int index,ValueT val)
    {
      if(_size <= index){
        ValueT* newArray = (ValueT*)realloc(_data,sizeof(ValueT)*(index+1));
        if(newArray){
          _data = newArray;
          _size = _count = index+1;
        }
      }
      _data[index]=val;
    }
  }
}
